writing TransactionTransfer Validation method, update tests

This commit is contained in:
Dario Rekowski on RockPI 2019-12-05 11:51:47 +00:00
parent da84873379
commit 18848f65ae
6 changed files with 145 additions and 9 deletions

View File

@ -49,7 +49,7 @@ class StateErrorsController extends AppController
}
$errors = $this->StateErrors->find('all')->where(['state_user_id' => $user['id']])->contain(false);
$transactionTypes = $this->StateErrors->TransactionTypes->find('all')->select(['id', 'name', 'text']);
$transactionTypes = $this->StateErrors->TransactionTypes->find('all')->select(['id', 'name', 'text'])->order(['id']);
$this->set('errors', $errors);
$this->set('transactionTypes', $transactionTypes->toList());

View File

@ -3,11 +3,10 @@
namespace Model\Transactions;
//use App\Model\Transactions\TransactionBase;
use Cake\ORM\TableRegistry;
class TransactionTransfer extends TransactionBase {
private $protoTransactionTransfer;
private $receiver_pubkey_hex;
private $sender_pubkey_hex;
public function __construct($protoTransactionTransfer) {
$this->protoTransactionTransfer = $protoTransactionTransfer;
@ -50,9 +49,107 @@ class TransactionTransfer extends TransactionBase {
}
public function validate($sigPairs) {
$this->addError('TransactionTransfer::validate', 'not implemented yet');
return false;
//return true;
//$this->addError('TransactionTransfer::validate', 'not implemented yet');
//return false;
//$time = microtime(true);
static $functionName = 'TransactionCreation::validate';
/*
* // check signature(s)
foreach($sigPairs as $sigPair) {
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
$pubkey = $sigPair->getPubKey();
$signature = $sigPair->getEd25519();
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
$this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
return false;
}
}
*/
$sigPubHexs = [];
foreach($sigPairs as $sigPair) {
//echo 'sig Pair: '; var_dump($sigPair); echo "<br>";
$pubkey = bin2hex($sigPair->getPubKey());
$hash = TransactionCreation::DRMakeStringHash($pubkey);
if(!isset($sigPubHexs[$hash])) {
$sigPubHexs[$hash] = [$pubkey];
} else {
array_push($sigPubHexs[$hash], $pubkey);
}
//array_push($sigPubHexs, $pubkey);
}
$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
$senderAmounts = $this->protoTransactionTransfer->getSenderAmounts();
$senderSum = 0;
$receiverSum = 0;
$senderPublics = [];
foreach($senderAmounts as $i => $senderAmount) {
$senderPublic = $senderAmount->getEd25519SenderPubkey();
$senderPublicHex = bin2hex($senderPublic);
array_push($senderPublics, $senderPublic);
if(strlen($senderPublicHex) != 64) {
$this->addError($functionName, 'invalid sender public key');
return false;
}
// check if signature exist for sender
$hash = TransactionCreation::DRMakeStringHash($senderPublicHex);
if(!isset($sigPubHexs[$hash]) || in_array($senderPublicHex, $sigPubHexs[$hash]) === FALSE) {
$this->addError($functionName, 'missing signature for sender');
return false;
}
// check if sender has enough Gradido
$amount = $senderAmount->getAmount();
$user = $stateUsersTable
->find('all')
->select(['id'])
->where(['public_key' => $senderPublic])
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]])->first();
if(!$user) {
$this->addError($functionName, 'couldn\'t find sender ' . $i .' in db' );
return false;
}
//var_dump($user);
if(intval($user->state_balances[0]->amount) < intval($amount)) {
$this->addError($functionName, 'sender ' . $i . ' hasn\t enough GDD');
return false;
}
$senderSum += $amount;
}
$uniqueSenderPublics = array_unique($senderPublics);
if(count($senderPublics) !== count($uniqueSenderPublics)) {
$this->addError($functionName, 'duplicate sender public key');
return false;
}
$receiverAmounts = $this->protoTransactionTransfer->getReceiverAmounts();
$receiverPublics = [];
foreach($receiverAmounts as $reveiverAmount) {
if(strlen($reveiverAmount->getEd25519ReceiverPubkey()) != 32) {
$this->addError($functionName, 'invalid receiver public key');
return false;
}
array_push($receiverPublics, $reveiverAmount->getEd25519ReceiverPubkey());
$receiverSum += $reveiverAmount->getAmount();
}
$uniqueReceiverPublic = array_unique($receiverPublics);
if(count($uniqueReceiverPublic) !== count($receiverPublics)) {
$this->addError($functionName, 'duplicate receiver public key');
return false;
}
$uniquePublics = array_unique(array_merge($receiverPublics, $senderPublics));
if(count($uniquePublics) !== count($senderPublics) + count($receiverPublics)) {
// means at least one sender is the same as one receiver
$this->addError($functionName, 'duplicate public in sender and receiver');
return false;
}
if($senderSum !== $receiverSum) {
$this->addError($functionName, 'sender amount doesn\'t match receiver amount');
return false;
}
//die("\n");
return true;
}
public function save($transaction_id, $firstPublic) {

View File

@ -21,11 +21,25 @@ $this->assign('title', __('Fehlermeldungen'));
</thead>
<tbody>
<?php foreach($errors as $error) :
$type = $transactionTypes[$error->transaction_type_id]; ?>
$type = $transactionTypes[$error->transaction_type_id-1];
$errorMessage = "";
$errorArray = json_decode($error->message_json, true);
if(isset($errorArray['details'])) {
foreach($errorArray['details'][0] as $function => $errorString) {
$errorMessage = '<b>' . $function . '</b><br> ' . $errorString;
}
} else {
$errorMessage = $error->message_json;
}
?>
<tr>
<td title="<?= $type->text ?>"><?= $type->name ?></td>
<td><?= $error->created ?></td>
<td><?= $error->message_json ?></td>
<td><?= $errorMessage ?></td>
<td><?= $this->Html->link(__('Delete'), ['action' => 'deleteForUser', $error->id], ['class' => 'grd-form-bn grd-form-bn-discard']) ?></td>
</tr>
<?php endforeach; ?>

View File

@ -42,6 +42,12 @@ class StateBalancesFixture extends TestFixture
'modified' => '2019-11-05 18:02:28',
'amount' => 1200
],
[
'id' => 10,
'state_user_id' => 4,
'modified' => '2019-11-11 14:58:54',
'amount' => 1200000
]
];
parent::init();
}

View File

@ -49,6 +49,15 @@ class StateUsersFixture extends TestFixture
'first_name' => 'Dario',
'last_name' => 'Rekowski'
],
[
'id' => 4,
'index_id' => 0,
'group_id' => 0,
'public_key' => hex2bin('8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d'),
'email' => 'dariofrodo@gmx.de',
'first_name' => 'Dario',
'last_name' => 'Frodo'
],
[
'id' => 11,
'index_id' => 0,

View File

@ -23,6 +23,7 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
'app.TransactionCreations',
'app.Transactions',
'app.StateUsers',
'app.StateErrors',
'app.TransactionSignatures',
'app.TransactionSendCoins',
'app.StateBalances',
@ -33,7 +34,8 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
'validCreation' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQJ8wF12eZo3hcMAlAKKJ9WLT-zuSkNmGh7D98UEqH4KoIysnCkXqEya9EBZl9o11_nJ8xmm_nOevuVjR-GfLMQ8qSQoOSGFsbG8gV2VsdCAxMjMSBgiZm4ruBUovCicKIJSuE1uTzZ8zdStOVcQZA6P6oTp1u5C_1BHqHUoaXnEfEKDakwEQtYntlgo',
'validCreation900' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQNVZ8Ae3Zbg3G0wZ840fzKan6N4KtTcSe0KYi17kQwFmsl18oFxXv8_s6j1xXFrIKjy1_1Olq0a7xYLErDMkjwYqORIGCNb5iu4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgNHKCBC1ie2WCg',
'validCreation1200' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQEEey5QMAdldoOTP_jTETHgOQriGsixEY0cziQeRfT_J5YtbI_A6AizEYD-JcxmRmXzv1xjjTgsV39Y32ta2CQkqORIGCIeGi-4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgOy4CxC1ie2WCg',
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3'
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3',
'validTransfer' => 'GmYKZAoggZC9pYXuXx2fv30G6B5p7BjhM3YQTP9Ut0V-t9PvcQ0SQDddHyKzAX3LBV0PuDiPc6lxkUipss5tyuLRpMtFJQnT30tsbYIkA1FXimjMKOoiuLswf4OLLV3bAIYehW-b9AgqYQoFSGFsbG8SBgiJlaPvBUJQCiYKIIGQvaWF7l8dn799BugeaewY4TN2EEz_VLdFfrfT73ENEICfSRImCiDtdleSLxhUgEbMW9DpqIwsykFj3-z_enKEOuGnXrmW8xCAn0k'
];
/*public function setUp() {
@ -125,6 +127,14 @@ class TransactionJsonRequestHandlerControllerTest extends TestCase
);
}
public function testValidTransfer()
{
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => $this->transactions['validTransfer']],
['state' => 'success']
);
}
/*public function testMissingPreviousTransaction()
{