Browse Source

server: Fix bug that corrupted the transaction outputs

For some reason, storing a list on an array column gets the row
corrupted.
develop
Alexis Hernandez 6 years ago
parent
commit
e91de5b6de
  1. 4
      server/app/com/xsn/explorer/data/anorm/dao/TransactionInputPostgresDAO.scala
  2. 4
      server/app/com/xsn/explorer/data/anorm/dao/TransactionOutputPostgresDAO.scala
  3. 10
      server/app/com/xsn/explorer/data/anorm/parsers/CommonParsers.scala
  4. 19
      server/test/com/xsn/explorer/data/TransactionPostgresDataHandlerSpec.scala
  5. 53
      server/test/resources/transactions/9969603dca74d14d29d1d5f56b94c7872551607f8c2d6837ab9715c60721b50e

4
server/app/com/xsn/explorer/data/anorm/dao/TransactionInputPostgresDAO.scala

@ -27,7 +27,7 @@ class TransactionInputPostgresDAO {
'from_txid -> input.fromTxid.string: NamedParameter,
'from_output_index -> input.fromOutputIndex: NamedParameter,
'value -> input.value: NamedParameter,
'addresses -> input.addresses.map(_.string): NamedParameter)
'addresses -> input.addresses.map(_.string).toArray: NamedParameter)
}
val batch = BatchSql(
@ -35,7 +35,7 @@ class TransactionInputPostgresDAO {
|INSERT INTO transaction_inputs
| (txid, index, from_txid, from_output_index, value, addresses)
|VALUES
| ({txid}, {index}, {from_txid}, {from_output_index}, {value}, ARRAY[{addresses}]::TEXT[])
| ({txid}, {index}, {from_txid}, {from_output_index}, {value}, {addresses})
""".stripMargin,
params.head,
params.tail: _*

4
server/app/com/xsn/explorer/data/anorm/dao/TransactionOutputPostgresDAO.scala

@ -52,7 +52,7 @@ class TransactionOutputPostgresDAO {
'txid -> output.txid.string: NamedParameter,
'index -> output.index: NamedParameter,
'value -> output.value: NamedParameter,
'addresses -> output.addresses.map(_.string): NamedParameter,
'addresses -> output.addresses.map(_.string).toArray: NamedParameter,
'hex_script -> output.script.string: NamedParameter)
}
@ -61,7 +61,7 @@ class TransactionOutputPostgresDAO {
|INSERT INTO transaction_outputs
| (txid, index, value, addresses, hex_script)
|VALUES
| ({txid}, {index}, {value}, ARRAY[{addresses}]::TEXT[], {hex_script})
| ({txid}, {index}, {value}, {addresses}, {hex_script})
""".stripMargin,
params.head,
params.tail: _*

10
server/app/com/xsn/explorer/data/anorm/parsers/CommonParsers.scala

@ -10,15 +10,19 @@ object CommonParsers {
.map { _.getOrElse(throw new RuntimeException(s"corrupted $field")) }
def parseAddress(field: String = "address") = str(field)
.map(Address.from)
.map { _.getOrElse(throw new RuntimeException(s"corrupted $field")) }
.map { string =>
Address.from(string) match {
case None => throw new RuntimeException(s"Corrupted $field: $string")
case Some(address) => address
}
}
def parseAddresses = array[String]("addresses")
.map { array =>
array
.map { string =>
Address.from(string) match {
case None => throw new RuntimeException("Corrupted address")
case None => throw new RuntimeException(s"Corrupted address: $string")
case Some(address) => address
}
}

19
server/test/com/xsn/explorer/data/TransactionPostgresDataHandlerSpec.scala

@ -12,9 +12,10 @@ import com.xsn.explorer.models._
import com.xsn.explorer.models.fields.TransactionField
import com.xsn.explorer.models.persisted.Transaction
import com.xsn.explorer.models.rpc.Block
import com.xsn.explorer.models.values.{Height, _}
import com.xsn.explorer.models.values._
import org.scalactic.{Bad, Good, One, Or}
import org.scalatest.BeforeAndAfter
import org.scalatest.EitherValues._
class TransactionPostgresDataHandlerSpec extends PostgresDataHandlerSpec with BeforeAndAfter {
@ -129,6 +130,22 @@ class TransactionPostgresDataHandlerSpec extends PostgresDataHandlerSpec with Be
val result = dataHandler.getOutput(txid, index)
result must be(Bad(TransactionNotFoundError).accumulating)
}
"not corrupt the output" in {
val txid = createTransactionId("9969603dca74d14d29d1d5f56b94c7872551607f8c2d6837ab9715c60721b50e")
val rpcTx = TransactionLoader.getWithValues(txid.string).copy(blockhash = block.hash)
val tx = Transaction.fromRPC(rpcTx)._1
val expected = Transaction.Output(
txid = txid,
index = 2,
value = 0.01,
addresses = List.empty,
script = HexString.from("0804678afd04678afd75a820894eeb82f9a851f5d1cb1be3249f58bc8d259963832c5e7474a76f7a859ee95c87").get)
upsertTransaction(tx)
val result = dataHandler.getOutput(txid, 2)
result.toEither.right.value must be(expected)
}
}
"getByBlockhash" should {

53
server/test/resources/transactions/9969603dca74d14d29d1d5f56b94c7872551607f8c2d6837ab9715c60721b50e

@ -0,0 +1,53 @@
{
"txid": "9969603dca74d14d29d1d5f56b94c7872551607f8c2d6837ab9715c60721b50e",
"hash": "9969603dca74d14d29d1d5f56b94c7872551607f8c2d6837ab9715c60721b50e",
"version": 1,
"size": 312,
"vsize": 312,
"weight": 1248,
"locktime": 0,
"vin": [
],
"vout": [
{
"value": 2.83595354,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 0568015a9facccfd09d70d409b6fc1a5546cecc6 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9140568015a9facccfd09d70d409b6fc1a5546cecc688ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"1VayNert3x1KzbpzMGt2qdqrAThiRovi8"
]
}
},
{
"value": 0.01,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 7f74e1560a03193e6c6782af4b9982eb111061e4 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9147f74e1560a03193e6c6782af4b9982eb111061e488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"1CcvqLs2SzckTsKRhpfk2JzPqkiqSkd6Hu"
]
}
},
{
"value": 0.01,
"n": 2,
"scriptPubKey": {
"asm": "04678afd04678afd OP_DROP OP_SHA256 894eeb82f9a851f5d1cb1be3249f58bc8d259963832c5e7474a76f7a859ee95c OP_EQUAL",
"hex": "0804678afd04678afd75a820894eeb82f9a851f5d1cb1be3249f58bc8d259963832c5e7474a76f7a859ee95c87",
"type": "nonstandard"
}
}
],
"hex": "010000000130b9400da79e83ebaf3fbb6c94f8ee0923e8d64c0089b2318fc9e68753a2d141000000008b483045022064e348746df42411ae5b1cab8b07a22736c42a9e58e336cdc8a5757beb929aa70221008419a71d5947f13586f6b28bc69fa185c289a7bffde174817bd5497109e339e2014104a39b9e4fbd213ef24bb9be69de4a118dd0644082e47c01fd9159d38637b83fbcdc115a5d6e970586a012d1cfe3e3a8b1a3d04e763bdc5a071c0e827c0bd834a5ffffffff035a52e710000000001976a9140568015a9facccfd09d70d409b6fc1a5546cecc688ac40420f00000000001976a9147f74e1560a03193e6c6782af4b9982eb111061e488ac40420f00000000002d0804678afd04678afd75a820894eeb82f9a851f5d1cb1be3249f58bc8d259963832c5e7474a76f7a859ee95c8700000000",
"blockhash": "0000000000000c903d611033d7f69368b69552f79bdedead19b53cf585ea780a",
"confirmations": 419994,
"time": 1321752937,
"blocktime": 1321752937
}
Loading…
Cancel
Save