aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2020-08-20 02:21:57 -0400
committerDeterminant <tederminant@gmail.com>2020-08-20 02:21:57 -0400
commitb3fb1dc6ed3c5610c03abdd6f2ff7bf164fb83ca (patch)
treefd8de359333b11f9178b05b054c9bbd3380bd903
parenta054d19f05a31a0421d6fe1bc534da46921481d5 (diff)
add flow check for ExportTx
-rw-r--r--plugin/evm/export_tx.go32
-rw-r--r--plugin/evm/vm.go7
2 files changed, 36 insertions, 3 deletions
diff --git a/plugin/evm/export_tx.go b/plugin/evm/export_tx.go
index 4f47a16..8b3c4f8 100644
--- a/plugin/evm/export_tx.go
+++ b/plugin/evm/export_tx.go
@@ -91,8 +91,36 @@ func (tx *UnsignedExportTx) SemanticVerify(
return permError{err}
}
- // TODO: credential check
- // TODO: flow check
+ f := crypto.FactorySECP256K1R{}
+ for i, cred := range stx.Creds {
+ if err := cred.Verify(); err != nil {
+ return permError{err}
+ }
+ pubKey, err := f.RecoverPublicKey(tx.UnsignedBytes(), cred.(*secp256k1fx.Credential).Sigs[0][:])
+ if err != nil {
+ return permError{err}
+ }
+ if tx.Ins[i].Address != PublicKeyToEthAddress(pubKey) {
+ return permError{errPublicKeySignatureMismatch}
+ }
+ }
+
+ // do flow-checking
+ fc := avax.NewFlowChecker()
+ fc.Produce(vm.ctx.AVAXAssetID, vm.txFee)
+
+ for _, out := range tx.ExportedOutputs {
+ fc.Produce(out.AssetID(), out.Output().Amount())
+ }
+
+ for _, in := range tx.Ins {
+ fc.Consume(vm.ctx.AVAXAssetID, in.Amount)
+ }
+
+ if err := fc.Verify(); err != nil {
+ return permError{err}
+ }
+
// TODO: verify UTXO outputs via gRPC
return nil
}
diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go
index 8823380..98ecb6f 100644
--- a/plugin/evm/vm.go
+++ b/plugin/evm/vm.go
@@ -175,6 +175,7 @@ func (vm *VM) getAtomicTx(block *types.Block) *Tx {
panic(err)
}
}
+ atx.Sign(vm.codec, nil)
return atx
}
@@ -719,8 +720,12 @@ func (vm *VM) GetAtomicUTXOs(
}
func GetEthAddress(privKey *crypto.PrivateKeySECP256K1R) common.Address {
+ return PublicKeyToEthAddress(privKey.PublicKey())
+}
+
+func PublicKeyToEthAddress(pubKey crypto.PublicKey) common.Address {
return ethcrypto.PubkeyToAddress(
- (*privKey.PublicKey().(*crypto.PublicKeySECP256K1R).ToECDSA()))
+ (*pubKey.(*crypto.PublicKeySECP256K1R).ToECDSA()))
}
func (vm *VM) GetSpendableCanonical(keys []*crypto.PrivateKeySECP256K1R, amount uint64) ([]EVMInput, [][]*crypto.PrivateKeySECP256K1R, error) {