diff --git a/config/load_test.go b/config/load_test.go index 71638409a..2da6cfd27 100644 --- a/config/load_test.go +++ b/config/load_test.go @@ -29,7 +29,7 @@ func Test_Load(t *testing.T) { require.NoError(t, err, "error loading config") // then - // verify not overriden default example value + // verify not overridden default example value assert.Equal(t, expectedConfig.GrpcMessageSize, actualConfig.GrpcMessageSize) // verify correct override diff --git a/go.mod b/go.mod index 5dd6d5367..dd04cee88 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-testfixtures/testfixtures/v3 v3.9.0 github.com/go-zeromq/zmq4 v0.17.0 github.com/golang-migrate/migrate/v4 v4.16.2 + github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 diff --git a/internal/blocktx/integration_test/reorg_integration_test.go b/internal/blocktx/integration_test/reorg_integration_test.go index f1e018df7..b0cb7e51f 100644 --- a/internal/blocktx/integration_test/reorg_integration_test.go +++ b/internal/blocktx/integration_test/reorg_integration_test.go @@ -25,10 +25,6 @@ import ( "testing" "time" - "github.com/bitcoin-sv/arc/internal/blocktx" - "github.com/bitcoin-sv/arc/internal/blocktx/blocktx_api" - "github.com/bitcoin-sv/arc/internal/blocktx/store/postgresql" - testutils "github.com/bitcoin-sv/arc/internal/test_utils" _ "github.com/golang-migrate/migrate/v4/source/file" _ "github.com/lib/pq" "github.com/libsv/go-p2p" @@ -36,6 +32,11 @@ import ( "github.com/libsv/go-p2p/wire" "github.com/ory/dockertest/v3" "github.com/stretchr/testify/require" + + "github.com/bitcoin-sv/arc/internal/blocktx" + "github.com/bitcoin-sv/arc/internal/blocktx/blocktx_api" + "github.com/bitcoin-sv/arc/internal/blocktx/store/postgresql" + testutils "github.com/bitcoin-sv/arc/internal/test_utils" ) const ( @@ -118,7 +119,7 @@ func TestBlockStatus(t *testing.T) { blockMessage := &p2p.BlockMessage{ Header: &wire.BlockHeader{ Version: 541065216, - PrevBlock: *prevBlockHash, // NON-existant in the db + PrevBlock: *prevBlockHash, // NON-existent in the db MerkleRoot: *merkleRoot, Bits: 0x1d00ffff, }, diff --git a/internal/blocktx/processor.go b/internal/blocktx/processor.go index 18b787ecb..d2d8a8e2f 100644 --- a/internal/blocktx/processor.go +++ b/internal/blocktx/processor.go @@ -448,7 +448,7 @@ func (p *Processor) processBlock(msg *p2p.BlockMessage) error { // with no blocks, to mark the first block as the LONGEST chain longestTipExists, err = p.longestTipExists(ctx) if err != nil { - p.logger.Error("unable to verify the longest tip existance in db", slog.String("hash", blockHash.String()), slog.Uint64("height", msg.Height), slog.String("err", err.Error())) + p.logger.Error("unable to verify the longest tip existence in db", slog.String("hash", blockHash.String()), slog.Uint64("height", msg.Height), slog.String("err", err.Error())) return err } } diff --git a/internal/node_client/config/bitcoin.conf b/internal/node_client/config/bitcoin.conf new file mode 100644 index 000000000..b6df95535 --- /dev/null +++ b/internal/node_client/config/bitcoin.conf @@ -0,0 +1,145 @@ +server=1 +rest=1 +listen=1 +regtest=1 +printtoconsole=1 +txindex=1 +dnsseed=0 +upnp=0 +usecashaddr=0 +debug=1 + +#Bind to given address to listen for JSON-RPC connections. Use +#[host]:port notation for IPv6. This option can be specified +#multiple times (default: bind to all interfaces) +#rpcbind= + +rpcport=18332 +rpcuser=bitcoin +rpcpassword=bitcoin +rpcallowip=0.0.0.0/0 + +port=18333 + +# onlynet=ipv4 +listenonion=0 +# prune=550 + +addressindex=1 +timestampindex=1 +spentindex=1 + +#Allow JSON-RPC connections from specified source. Valid for are a +#single IP (e.g. 1.2.3.4), a network/netmask (e.g. +#1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This +#option can be specified multiple times +#rpcallowip= +#Set the number of threads to service RPC calls (default: 4) +rpcthreads=24 + +#Set the depth of the work queue to service RPC calls (default: 16) +rpcworkqueue=600 + +#Timeout during HTTP requests (default: 30) +#rpcservertimeout= +blockmaxsize=512000000 +excessiveblocksize=2000000000 +maxstackmemoryusageconsensus=200000000 + +#connect=142.93.36.189:9988 + +#node filter +#whitelist=127.0.0.1 + +#Append comment to the user agent string +#uacomment= + +#Maximum database write batch size in bytes (default: 16777216) +#dbbatchsize=16777216 + +#Set database cache size in megabytes (4 to 16384, default: 450) +dbcache=16384 + +#Limit size of signature cache to MiB (default: 32) +maxsigcachesize=260 + +#Limit size of script cache to MiB (default: 32) +maxscriptcachesize=260 + +#Keep at most unconnectable transactions in memory (default: 100) +maxorphantx=100000 + +#Keep the transaction memory pool below megabytes (default: 300) +maxmempool=2000 + +#Do not keep transactions in the mempool longer than hours (default: 336) +#mempoolexpiry=48 + +#Extra transactions to keep in memory for compact block reconstructions(default: 100) +blockreconstructionextratxn=100000 + +#Set the number of script verification threads (-4 to 16, 0 = auto, <0 = +#leave that many cores free, default: 0) +#par= + +#Threshold for disconnecting misbehaving peers (default: 100) +banscore=10000 + +#Number of seconds to keep misbehaving peers from reconnecting (default: 86400) +#bantime= + +#Maintain at most connections to peers (default: 125) +#maxconnections= + +#Maximum per-connection receive buffer, *1000 bytes (default: 5000) +#maxreceivebuffer= + +#Maximum per-connection send buffer, *1000 bytes (default: 1000) +#maxsendbuffer= + +#Specify connection timeout in milliseconds (minimum: 1, default: 5000) +#timeout= + +#ZeroMQ notification options: + +#Enable publish hash block in
+zmqpubhashblock=tcp://*:28332 + +#Enable publish hash transaction in
+zmqpubhashtx=tcp://*:28332 +zmqpubhashtx2=tcp://*:28332 + +#Enable publish raw block in
+zmqpubrawblock=tcp://*:28332 +zmqpubrawblock2=tcp://*:28332 + +#Enable publish raw transaction in
+zmqpubrawtx=tcp://*:28332 + +invalidtxsink=ZMQ +zmqpubinvalidtx=tcp://*:28332 +zmqpubdiscardedfrommempool=tcp://*:28332 + +#Do not accept transactions if number of in-mempool ancestors is or more (default: 1000) +#limitancestorcount= + +#Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: 101) +#limitancestorsize= + +#Do not accept transactions if any ancestor would have or more in-mempool descendants (default: 25) +#limitdescendantcount= + +#Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: 101). +#limitdescendantsize= + +#Fees (in BCH/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: 0.00001) +#minrelaytxfee= + +#Relay and mine "non-standard" transactions (testnet/regtest only; default: 1) +#acceptnonstdtxn=0 + +#Use genesis rules from the 1st block instead of waiting until 10,000 (default) blocks to activate genesis rules. +genesisactivationheight=1 + +minminingtxfee=0.0000005 +whitelist=172.20.0.1/32 diff --git a/internal/node_client/node_client.go b/internal/node_client/node_client.go index 2a69228b6..7a56f1868 100644 --- a/internal/node_client/node_client.go +++ b/internal/node_client/node_client.go @@ -1,3 +1,108 @@ package node_client -// Todo: Implement node client +import ( + "context" + "encoding/json" + "errors" + "fmt" + "runtime" + + sdkTx "github.com/bitcoin-sv/go-sdk/transaction" + "github.com/ordishs/go-bitcoin" + "go.opentelemetry.io/otel/attribute" + + "github.com/bitcoin-sv/arc/internal/tracing" +) + +var ( + ErrFailedToGetRawTransaction = errors.New("failed to get raw transaction") + ErrFailedToGetMempoolAncestors = errors.New("failed to get mempool ancestors") +) + +type NodeClient struct { + bitcoinClient *bitcoin.Bitcoind + tracingEnabled bool + tracingAttributes []attribute.KeyValue +} + +func WithTracer(attr ...attribute.KeyValue) func(s *NodeClient) { + return func(p *NodeClient) { + p.tracingEnabled = true + if len(attr) > 0 { + p.tracingAttributes = append(p.tracingAttributes, attr...) + } + _, file, _, ok := runtime.Caller(1) + if ok { + p.tracingAttributes = append(p.tracingAttributes, attribute.String("file", file)) + } + } +} + +func New(n *bitcoin.Bitcoind, opts ...func(client *NodeClient)) (NodeClient, error) { + node := NodeClient{ + bitcoinClient: n, + } + + for _, opt := range opts { + opt(&node) + } + + return node, nil +} + +func (n NodeClient) GetMempoolAncestors(ctx context.Context, ids []string) ([]string, error) { + _, span := tracing.StartTracing(ctx, "NodeClient_GetMempoolAncestors", n.tracingEnabled, n.tracingAttributes...) + defer tracing.EndTracing(span) + + uniqueIDs := make(map[string]struct{}) + + for _, id := range ids { + _, span := tracing.StartTracing(ctx, "Bitcoind_GetMempoolAncestors", n.tracingEnabled, n.tracingAttributes...) + nTx, err := n.bitcoinClient.GetMempoolAncestors(id, false) + tracing.EndTracing(span) + if err != nil { + return nil, errors.Join(ErrFailedToGetMempoolAncestors, err) + } + + if nTx == nil { + return nil, nil + } + + var txIDs []string + + err = json.Unmarshal(nTx, &txIDs) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal raw transaction: %v", err) + } + + for _, txID := range txIDs { + uniqueIDs[txID] = struct{}{} + } + } + + allTxIDs := make([]string, len(uniqueIDs)) + counter := 0 + for id := range uniqueIDs { + allTxIDs[counter] = id + counter++ + } + return allTxIDs, nil +} + +func (n NodeClient) GetRawTransaction(ctx context.Context, id string) (*sdkTx.Transaction, error) { + _, span := tracing.StartTracing(ctx, "NodeClient_GetRawTransaction", n.tracingEnabled, n.tracingAttributes...) + defer tracing.EndTracing(span) + + nTx, err := n.bitcoinClient.GetRawTransaction(id) + + if err != nil { + return nil, errors.Join(ErrFailedToGetRawTransaction, err) + } + + rt, err := sdkTx.NewTransactionFromHex(nTx.Hex) + if err != nil { + return nil, err + } + + return rt, nil +} diff --git a/internal/node_client/node_client_test.go b/internal/node_client/node_client_test.go new file mode 100644 index 000000000..f36713905 --- /dev/null +++ b/internal/node_client/node_client_test.go @@ -0,0 +1,159 @@ +package node_client_test + +import ( + "context" + "log" + "os" + "strconv" + "testing" + + sdkTx "github.com/bitcoin-sv/go-sdk/transaction" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/ordishs/go-bitcoin" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/require" + + "github.com/bitcoin-sv/arc/internal/node_client" + testutils "github.com/bitcoin-sv/arc/internal/test_utils" +) + +var ( + hostPort int + bitcoind *bitcoin.Bitcoind +) + +const ( + host = "localhost" + port = 18332 + user = "bitcoin" + password = "bitcoin" +) + +func TestMain(m *testing.M) { + os.Exit(testmain(m)) +} + +func testmain(m *testing.M) int { + pool, err := dockertest.NewPool("") + if err != nil { + log.Printf("failed to create pool: %v", err) + return 1 + } + + cmds := []string{"/entrypoint.sh", "bitcoind"} + + resource, resourcePort, err := testutils.RunNode(pool, strconv.Itoa(port), "node", cmds...) + if err != nil { + log.Print(err) + return 1 + } + defer func() { + err = pool.Purge(resource) + if err != nil { + log.Fatalf("failed to purge pool: %v", err) + } + }() + + hostPort, err = strconv.Atoi(resourcePort) + if err != nil { + log.Fatalf("failed to convert port to int: %v", err) + } + + return m.Run() +} + +func setup() { + log.Printf("init tests") + + var err error + bitcoind, err = bitcoin.New(host, hostPort, user, password, false) + if err != nil { + log.Fatalln("Failed to create bitcoind instance:", err) + } + + _, err = bitcoind.GetInfo() + if err != nil { + log.Fatalln(err) + } + + // fund node + const minNumbeOfBlocks = 101 + _, err = bitcoind.Generate(minNumbeOfBlocks) + if err != nil { + log.Fatalln(err) + } +} + +func TestNodeClient(t *testing.T) { + t.Helper() + if testing.Short() { + t.Skip("skipping integration test") + } + + ctx := context.Background() + + setup() + + sut, err := node_client.New(bitcoind) + require.NoError(t, err) + + address, privateKey := node_client.FundNewWallet(t, bitcoind) + + utxos := node_client.GetUtxos(t, bitcoind, address) + require.True(t, len(utxos) > 0, "No UTXOs available for the address") + + t.Run("get raw transaction", func(t *testing.T) { + // given + var rawTx *sdkTx.Transaction + + // when + rawTx, err = sut.GetRawTransaction(ctx, utxos[0].Txid) + + // then + require.NoError(t, err) + + require.Equal(t, utxos[0].Txid, rawTx.TxID()) + + // when + _, err = sut.GetRawTransaction(ctx, "not areal id") + + // then + require.ErrorIs(t, err, node_client.ErrFailedToGetRawTransaction) + }) + + t.Run("get mempool ancestors", func(t *testing.T) { + // given + txs, err := node_client.CreateTxChain(privateKey, utxos[0], 20) + require.NoError(t, err) + + expectedTxIDs := make([]string, len(txs)-1) + for i, tx := range txs { + _, err := bitcoind.SendRawTransaction(tx.String()) + require.NoError(t, err) + + if i != len(txs)-1 { + expectedTxIDs[i] = tx.TxID() + } + } + + // when + ancestorTxIDs, err := sut.GetMempoolAncestors(ctx, []string{txs[len(txs)-1].TxID()}) + + // then + require.NoError(t, err) + require.Len(t, ancestorTxIDs, len(txs)-1) + + // compare expected and actual ancestor tx IDs while ignoring the order + less := func(a, b string) bool { return a < b } + equalIgnoreOrder := cmp.Diff(expectedTxIDs, ancestorTxIDs, cmpopts.SortSlices(less)) == "" + + require.True(t, equalIgnoreOrder) + + // when + _, err = sut.GetMempoolAncestors(ctx, []string{"not a real id"}) + + // then + require.ErrorIs(t, err, node_client.ErrFailedToGetMempoolAncestors) + }) +} diff --git a/internal/test_utils/docker.go b/internal/test_utils/docker.go index 20be90a14..212aa9615 100644 --- a/internal/test_utils/docker.go +++ b/internal/test_utils/docker.go @@ -3,7 +3,10 @@ package testutils import ( "errors" "fmt" + "net/url" + "os" + "github.com/ordishs/go-bitcoin" "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" @@ -100,3 +103,68 @@ func RunNats(pool *dockertest.Pool, port, name string, cmds ...string) (*dockert return resource, natsURL, nil } + +func RunNode(pool *dockertest.Pool, port, name string, cmds ...string) (*dockertest.Resource, string, error) { + pwd, err := os.Getwd() + if err != nil { + return nil, "", fmt.Errorf("failed to get current directory: %v", err) + } + + opts := dockertest.RunOptions{ + Repository: "bitcoinsv/bitcoin-sv", + Tag: "1.1.0", + ExposedPorts: []string{"18332"}, + PortBindings: map[docker.Port][]docker.PortBinding{ + "18332": { + {HostIP: "0.0.0.0", HostPort: port}, + }, + }, + Name: name, + Cmd: cmds, + } + + resource, err := pool.RunWithOptions(&opts, func(config *docker.HostConfig) { + // set AutoRemove to true so that stopped container goes away by itself + config.AutoRemove = true + config.RestartPolicy = docker.RestartPolicy{ + Name: "no", + } + + config.Mounts = []docker.HostMount{ + { + Target: "/data/bitcoin.conf", + Source: fmt.Sprintf("%s/config/bitcoin.conf", pwd), + Type: "bind", + }, + } + }) + if err != nil { + return nil, "", fmt.Errorf("failed to create resource: %v", err) + } + + hostPort := resource.GetPort("18332/tcp") + + rpcURL, err := url.Parse(fmt.Sprintf("rpc://%s:%s@%s:%s", "bitcoin", "bitcoin", "localhost", port)) + if err != nil { + return nil, "", fmt.Errorf("failed to parse node rpc url: %w", err) + } + + err = pool.Retry(func() error { + var retryErr error + n, retryErr := bitcoin.NewFromURL(rpcURL, false) + if retryErr != nil { + return retryErr + } + _, retryErr = n.GetInfo() + if retryErr != nil { + return retryErr + } + + return nil + }) + if err != nil { + return nil, "", fmt.Errorf("failed to create resource: %v", err) + } + + return resource, hostPort, nil +} diff --git a/internal/validator/beef/beef_validator_test.go b/internal/validator/beef/beef_validator_test.go index c7e01407e..c8860f2c9 100644 --- a/internal/validator/beef/beef_validator_test.go +++ b/internal/validator/beef/beef_validator_test.go @@ -7,15 +7,16 @@ import ( "errors" "testing" + "github.com/ordishs/go-bitcoin" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/bitcoin-sv/arc/internal/beef" "github.com/bitcoin-sv/arc/internal/fees" "github.com/bitcoin-sv/arc/internal/testdata" validation "github.com/bitcoin-sv/arc/internal/validator" "github.com/bitcoin-sv/arc/internal/validator/mocks" "github.com/bitcoin-sv/arc/pkg/api" - "github.com/ordishs/go-bitcoin" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestBeefValidator(t *testing.T) { @@ -46,7 +47,7 @@ func TestBeefValidator(t *testing.T) { expectedErrTxID: "8184849de6af441c7de088428073c2a9131b08f7d878d9f49c3faf6d941eb168", }, { - name: "invlid beef - invalid scripts", + name: "invalid beef - invalid scripts", beefStr: "0100beef01fe4e6d0c001002fd909002088a382ec07a8cf47c6158b68e5822852362102d8571482d1257e0b7527e1882fd91900065cb01218f2506bb51155d243e4d6b32d69d1b5f2221c52e26963cfd8cf7283201fd4948008d7a44ae384797b0ae84db0c857e8c1083425d64d09ef8bc5e2e9d270677260501fd25240060f38aa33631c8d70adbac1213e7a5b418c90414e919e3a12ced63dd152fd85a01fd1312005ff132ee64a7a0c79150a29f66ef861e552d3a05b47d6303f5d8a2b2a09bc61501fd080900cc0baf21cf06b9439dfe05dce9bdb14ddc2ca2d560b1138296ef5769851a84b301fd85040063ccb26232a6e1d3becdb47a0f19a67a562b754e8894155b3ae7bba10335ce5101fd430200e153fc455a0f2c8372885c11af70af904dcf44740b9ebf3b3e5b2234cce550bc01fd20010077d5ea69d1dcc379dde65d6adcebde1838190118a8fae928c037275e78bd87910191000263e4f31684a25169857f2788aeef603504931f92585f02c4c9e023b2aa43d1014900de72292e0b3e5eeacfa2b657bf4d46c885559b081ee78632a99b318c1148d85c01250068a5f831ca99b9e7f3720920d6ea977fd2ab52b83d1a6567dafa4c8cafd941ed0113006a0b91d83f9056b702d6a8056af6365c7da626fc3818b815dd4b0de22d05450f0108009876ce56b68545a75859e93d200bdde7880d46f39384818b259ed847a9664ddf010500990bc5e95cacbc927b5786ec39a183f983fe160d52829cf47521c7eb369771c30103004fe794e50305f590b6010a51d050bf47dfeaabfdb949c5ee0673f577a59537d70100004dad44a358aea4d8bc1917912539901f5ae44e07a4748e1a9d3018814b0759d0020100000002704273c86298166ac351c3aa9ac90a8029e4213b5f1b03c3bbf4bc5fb09cdd43010000006a4730440220398d6389e8a156a3c6c1ca355e446d844fd480193a93af832afd1c87d0f04784022050091076b8f7405b37ce6e795d1b92526396ac2b14f08e91649b908e711e2b044121030ef6975d46dbab4b632ef62fdbe97de56d183be1acc0be641d2c400ae01cf136ffffffff2f41ed6a2488ac3ba4a3c330a15fa8193af87f0192aa59935e6c6401d92dc3a00a0000006a47304402200ad9cf0dc9c90a4c58b08910740b4a8b3e1a7e37db1bc5f656361b93f412883d0220380b6b3d587103fc8bf3fe7bed19ab375766984c67ebb7d43c993bcd199f32a441210205ef4171f58213b5a2ddf16ac6038c10a2a8c3edc1e6275cb943af4bb3a58182ffffffff03e8030000000000001976a9148a8c4546a95e6fc8d18076a9980d59fd882b4e6988acf4010000000000001976a914c7662da5e0a6a179141a7872045538126f1e954288acf5000000000000001976a914765bdf10934f5aac894cf8a3795c9eeb494c013488ac0000000001000100000001088a382ec07a8cf47c6158b68e5822852362102d8571482d1257e0b7527e1882000000006a4730440220610bba9ed83a47641c34bbbcf8eeb536d2ae6cfddc7644a8c520bb747f798c3702206a23c9f45273772dd7e80ba21a5c4613d6ffe7ba1c75b729eae0cdd484fee2bd412103c0cd91af135d09f98d57e34af28e307daf36bccd4764708e8a3f7ea5cebf01a9ffffffff01c8000000000000001976a9148ce2d21f9a75e98600be76b25b91c4fef6b40bcd88ac0000000000", expectedErr: validation.NewError(errors.New("invalid script"), api.ErrStatusUnlockingScripts), expectedErrTxID: "ea2924da32c47b9942cda5ad30d3c01610ca554ca3a9ca01b2ccfe72bf0667be", @@ -147,7 +148,7 @@ func TestValidateScripts(t *testing.T) { expectedError: nil, }, { - name: "Invlid Beef - Invalid Scripts", + name: "Invalid Beef - Invalid Scripts", beefStr: "0100beef01fe4e6d0c001002fd909002088a382ec07a8cf47c6158b68e5822852362102d8571482d1257e0b7527e1882fd91900065cb01218f2506bb51155d243e4d6b32d69d1b5f2221c52e26963cfd8cf7283201fd4948008d7a44ae384797b0ae84db0c857e8c1083425d64d09ef8bc5e2e9d270677260501fd25240060f38aa33631c8d70adbac1213e7a5b418c90414e919e3a12ced63dd152fd85a01fd1312005ff132ee64a7a0c79150a29f66ef861e552d3a05b47d6303f5d8a2b2a09bc61501fd080900cc0baf21cf06b9439dfe05dce9bdb14ddc2ca2d560b1138296ef5769851a84b301fd85040063ccb26232a6e1d3becdb47a0f19a67a562b754e8894155b3ae7bba10335ce5101fd430200e153fc455a0f2c8372885c11af70af904dcf44740b9ebf3b3e5b2234cce550bc01fd20010077d5ea69d1dcc379dde65d6adcebde1838190118a8fae928c037275e78bd87910191000263e4f31684a25169857f2788aeef603504931f92585f02c4c9e023b2aa43d1014900de72292e0b3e5eeacfa2b657bf4d46c885559b081ee78632a99b318c1148d85c01250068a5f831ca99b9e7f3720920d6ea977fd2ab52b83d1a6567dafa4c8cafd941ed0113006a0b91d83f9056b702d6a8056af6365c7da626fc3818b815dd4b0de22d05450f0108009876ce56b68545a75859e93d200bdde7880d46f39384818b259ed847a9664ddf010500990bc5e95cacbc927b5786ec39a183f983fe160d52829cf47521c7eb369771c30103004fe794e50305f590b6010a51d050bf47dfeaabfdb949c5ee0673f577a59537d70100004dad44a358aea4d8bc1917912539901f5ae44e07a4748e1a9d3018814b0759d0020100000002704273c86298166ac351c3aa9ac90a8029e4213b5f1b03c3bbf4bc5fb09cdd43010000006a4730440220398d6389e8a156a3c6c1ca355e446d844fd480193a93af832afd1c87d0f04784022050091076b8f7405b37ce6e795d1b92526396ac2b14f08e91649b908e711e2b044121030ef6975d46dbab4b632ef62fdbe97de56d183be1acc0be641d2c400ae01cf136ffffffff2f41ed6a2488ac3ba4a3c330a15fa8193af87f0192aa59935e6c6401d92dc3a00a0000006a47304402200ad9cf0dc9c90a4c58b08910740b4a8b3e1a7e37db1bc5f656361b93f412883d0220380b6b3d587103fc8bf3fe7bed19ab375766984c67ebb7d43c993bcd199f32a441210205ef4171f58213b5a2ddf16ac6038c10a2a8c3edc1e6275cb943af4bb3a58182ffffffff03e8030000000000001976a9148a8c4546a95e6fc8d18076a9980d59fd882b4e6988acf4010000000000001976a914c7662da5e0a6a179141a7872045538126f1e954288acf5000000000000001976a914765bdf10934f5aac894cf8a3795c9eeb494c013488ac0000000001000100000001088a382ec07a8cf47c6158b68e5822852362102d8571482d1257e0b7527e1882000000006a4730440220610bba9ed83a47641c34bbbcf8eeb536d2ae6cfddc7644a8c520bb747f798c3702206a23c9f45273772dd7e80ba21a5c4613d6ffe7ba1c75b729eae0cdd484fee2bd412103c0cd91af135d09f98d57e34af28e307daf36bccd4764708e8a3f7ea5cebf01a9ffffffff01c8000000000000001976a9148ce2d21f9a75e98600be76b25b91c4fef6b40bcd88ac0000000000", expectedError: validation.NewError(errors.New("invalid script"), api.ErrStatusUnlockingScripts), }, diff --git a/pkg/api/handler/default.go b/pkg/api/handler/default.go index fea16269b..8115c8220 100644 --- a/pkg/api/handler/default.go +++ b/pkg/api/handler/default.go @@ -26,8 +26,8 @@ import ( "github.com/bitcoin-sv/arc/internal/version" "github.com/bitcoin-sv/arc/internal/woc_client" "github.com/bitcoin-sv/arc/pkg/api" - merkleverifier "github.com/bitcoin-sv/arc/pkg/api/handler/internal/MerkeVerifier" - txfinder "github.com/bitcoin-sv/arc/pkg/api/handler/internal/TxFinder" + "github.com/bitcoin-sv/arc/pkg/api/handler/internal/merkle_verifier" + txfinder "github.com/bitcoin-sv/arc/pkg/api/handler/internal/tx_finder" "github.com/bitcoin-sv/arc/pkg/blocktx" "github.com/bitcoin-sv/arc/pkg/metamorph" ) @@ -101,7 +101,7 @@ func NewDefault( wocClient = woc_client.New(false) } - mr := merkleverifier.New(merkleRootsVerifier) + mr := merkle_verifier.New(merkleRootsVerifier) handler := &ArcDefaultHandler{ TransactionHandler: transactionHandler, diff --git a/pkg/api/handler/internal/MerkeVerifier/merkle_verifier_adapter.go b/pkg/api/handler/internal/merkle_verifier/merkle_verifier_adapter.go similarity index 97% rename from pkg/api/handler/internal/MerkeVerifier/merkle_verifier_adapter.go rename to pkg/api/handler/internal/merkle_verifier/merkle_verifier_adapter.go index f0f0795d5..1e33111cf 100644 --- a/pkg/api/handler/internal/MerkeVerifier/merkle_verifier_adapter.go +++ b/pkg/api/handler/internal/merkle_verifier/merkle_verifier_adapter.go @@ -1,4 +1,4 @@ -package merkleverifier +package merkle_verifier import ( "context" diff --git a/pkg/api/handler/internal/TxFinder/cached_tx_finder.go b/pkg/api/handler/internal/tx_finder/cached_tx_finder.go similarity index 100% rename from pkg/api/handler/internal/TxFinder/cached_tx_finder.go rename to pkg/api/handler/internal/tx_finder/cached_tx_finder.go diff --git a/pkg/api/handler/internal/TxFinder/cached_tx_finder_test.go b/pkg/api/handler/internal/tx_finder/cached_tx_finder_test.go similarity index 100% rename from pkg/api/handler/internal/TxFinder/cached_tx_finder_test.go rename to pkg/api/handler/internal/tx_finder/cached_tx_finder_test.go diff --git a/pkg/api/handler/internal/TxFinder/tx_finder.go b/pkg/api/handler/internal/tx_finder/tx_finder.go similarity index 100% rename from pkg/api/handler/internal/TxFinder/tx_finder.go rename to pkg/api/handler/internal/tx_finder/tx_finder.go diff --git a/pkg/api/handler/internal/TxFinder/tx_finder_test.go b/pkg/api/handler/internal/tx_finder/tx_finder_test.go similarity index 100% rename from pkg/api/handler/internal/TxFinder/tx_finder_test.go rename to pkg/api/handler/internal/tx_finder/tx_finder_test.go diff --git a/pkg/blocktx/client.go b/pkg/blocktx/client.go index 50ef2200d..7073947b4 100644 --- a/pkg/blocktx/client.go +++ b/pkg/blocktx/client.go @@ -23,9 +23,9 @@ type Watcher interface { DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) (int64, error) } -// MerkleRootsVerifier verifies the merkle roots existance in blocktx db and returns unverified block heights. +// MerkleRootsVerifier verifies the merkle roots existence in blocktx db and returns unverified block heights. type MerkleRootsVerifier interface { - // VerifyMerkleRoots verifies the merkle roots existance in blocktx db and returns unverified block heights. + // VerifyMerkleRoots verifies the merkle roots existence in blocktx db and returns unverified block heights. VerifyMerkleRoots(ctx context.Context, merkleRootVerificationRequest []MerkleRootVerificationRequest) ([]uint64, error) } diff --git a/test/init_test.go b/test/init_test.go index b44a8b794..f41f69cd2 100644 --- a/test/init_test.go +++ b/test/init_test.go @@ -27,12 +27,9 @@ func TestMain(m *testing.M) { func setupSut() { log.Printf("init tests") - if os.Getenv("NODE_HOST") != "" { - nodeHost = os.Getenv("NODE_HOST") - } - - if os.Getenv("ARC_ENDPOINT") != "" { - arcEndpoint = os.Getenv("ARC_ENDPOINT") + if os.Getenv("TEST_LOCAL") != "" { + nodeHost = "localhost" + arcEndpoint = "http://localhost:9090/" arcEndpointV1Tx = arcEndpoint + v1Tx arcEndpointV1Txs = arcEndpoint + v1Txs } diff --git a/test/submit_01_single_test.go b/test/submit_01_single_test.go index 349e848d5..5897d4246 100644 --- a/test/submit_01_single_test.go +++ b/test/submit_01_single_test.go @@ -581,7 +581,7 @@ func TestPostCumulativeFeesValidation(t *testing.T) { expectedError string }{ { - name: "post zero fee txs chain with cumulative fees validation and with skiping fee validation - fee validation is ommited", + name: "post zero fee txs chain with cumulative fees validation and with skipping fee validation - fee validation is omitted", options: validationOpts{ performCumulativeFeesValidation: true, skipFeeValidation: true, @@ -590,7 +590,7 @@ func TestPostCumulativeFeesValidation(t *testing.T) { expectedTxStatus: StatusSeenOnNetwork, }, { - name: "post zero fee tx with cumulative fees validation and with skiping cumulative fee validation - cumulative fee validation is ommited", + name: "post zero fee tx with cumulative fees validation and with skipping cumulative fee validation - cumulative fee validation is omitted", options: validationOpts{ performCumulativeFeesValidation: false, }, @@ -719,7 +719,7 @@ func TestPostCumulativeFeesValidation(t *testing.T) { // create last transaction var nodeUtxos []node_client.UnspentOutput for _, chain := range zeroFeeChains { - // get otput from the lastes tx in the chain + // get output from the latest tx in the chain parentTx := chain[len(chain)-1] output := parentTx.Outputs[0] utxo := node_client.UnspentOutput{