AVM code cleanup

This commit is contained in:
StephenButtolph 2020-03-19 18:36:10 -04:00
parent 29282f07ac
commit 638cce84ce
19 changed files with 250 additions and 504 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/ava-labs/gecko/snow"
"github.com/ava-labs/gecko/utils/math"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
var (
@ -155,11 +156,11 @@ func (t *BaseTx) SyntacticVerify(ctx *snow.Context, c codec.Codec, _ int) error
}
// SemanticVerify that this transaction is valid to be spent.
func (t *BaseTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) error {
func (t *BaseTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiable) error {
for i, in := range t.Ins {
cred := creds[i]
fxIndex, err := vm.getFx(cred.Cred)
fxIndex, err := vm.getFx(cred)
if err != nil {
return err
}
@ -178,7 +179,7 @@ func (t *BaseTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) erro
return errIncompatibleFx
}
err = fx.VerifyTransfer(uTx, utxo.Out, in.In, cred.Cred)
err = fx.VerifyTransfer(uTx, utxo.Out, in.In, cred)
if err == nil {
continue
}
@ -215,7 +216,7 @@ func (t *BaseTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) erro
return errIncompatibleFx
}
if err := fx.VerifyTransfer(uTx, utxo.Out, in.In, cred.Cred); err != nil {
if err := fx.VerifyTransfer(uTx, utxo.Out, in.In, cred); err != nil {
return err
}
}

View File

@ -797,7 +797,7 @@ func TestBaseTxSemanticVerify(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -819,7 +819,7 @@ func TestBaseTxSemanticVerify(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -834,11 +834,9 @@ func TestBaseTxSemanticVerify(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -849,11 +847,11 @@ func TestBaseTxSemanticVerify(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err != nil {
@ -889,7 +887,7 @@ func TestBaseTxSemanticVerifyUnknownFx(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -911,11 +909,9 @@ func TestBaseTxSemanticVerifyUnknownFx(t *testing.T) {
},
},
},
}}}
}}
tx.Creds = append(tx.Creds, &Credential{
Cred: &testVerifiable{},
})
tx.Creds = append(tx.Creds, &testVerifiable{})
b, err := vm.codec.Marshal(tx)
if err != nil {
@ -924,11 +920,11 @@ func TestBaseTxSemanticVerifyUnknownFx(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -964,7 +960,7 @@ func TestBaseTxSemanticVerifyWrongAssetID(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -986,7 +982,7 @@ func TestBaseTxSemanticVerifyWrongAssetID(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1001,11 +997,9 @@ func TestBaseTxSemanticVerifyWrongAssetID(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1016,11 +1010,11 @@ func TestBaseTxSemanticVerifyWrongAssetID(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1068,7 +1062,7 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1083,7 +1077,7 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
In: &TestTransferable{},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1098,11 +1092,9 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1113,11 +1105,11 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1151,7 +1143,7 @@ func TestBaseTxSemanticVerifyInvalidSignature(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1173,13 +1165,11 @@ func TestBaseTxSemanticVerifyInvalidSignature(t *testing.T) {
},
},
},
}}}
}}
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
[crypto.SECP256K1RSigLen]byte{},
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
[crypto.SECP256K1RSigLen]byte{},
},
})
@ -1190,11 +1180,11 @@ func TestBaseTxSemanticVerifyInvalidSignature(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1228,7 +1218,7 @@ func TestBaseTxSemanticVerifyMissingUTXO(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1250,7 +1240,7 @@ func TestBaseTxSemanticVerifyMissingUTXO(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1265,11 +1255,9 @@ func TestBaseTxSemanticVerifyMissingUTXO(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1280,11 +1268,11 @@ func TestBaseTxSemanticVerifyMissingUTXO(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1318,7 +1306,7 @@ func TestBaseTxSemanticVerifyInvalidUTXO(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1340,7 +1328,7 @@ func TestBaseTxSemanticVerifyInvalidUTXO(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1355,11 +1343,9 @@ func TestBaseTxSemanticVerifyInvalidUTXO(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1370,11 +1356,11 @@ func TestBaseTxSemanticVerifyInvalidUTXO(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1407,7 +1393,7 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
pendingTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
pendingTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1444,7 +1430,7 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&pendingTx.UnsignedTx)
if err != nil {
@ -1459,11 +1445,9 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
pendingTx.Creds = append(pendingTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
pendingTx.Creds = append(pendingTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1486,7 +1470,7 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
vm.PendingTxs()
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1508,7 +1492,7 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err = vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1522,11 +1506,9 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
fixedSig = [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1537,11 +1519,11 @@ func TestBaseTxSemanticVerifyPendingInvalidUTXO(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1574,7 +1556,7 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
pendingTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
pendingTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1611,7 +1593,7 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&pendingTx.UnsignedTx)
if err != nil {
@ -1626,11 +1608,9 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
pendingTx.Creds = append(pendingTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
pendingTx.Creds = append(pendingTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1653,7 +1633,7 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
vm.PendingTxs()
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1675,7 +1655,7 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err = vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
@ -1689,11 +1669,9 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
fixedSig = [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1704,11 +1682,11 @@ func TestBaseTxSemanticVerifyPendingWrongAssetID(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1755,7 +1733,7 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
pendingTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
pendingTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1792,7 +1770,7 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&pendingTx.UnsignedTx)
if err != nil {
@ -1807,11 +1785,9 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
pendingTx.Creds = append(pendingTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
pendingTx.Creds = append(pendingTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1834,7 +1810,7 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
vm.PendingTxs()
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1856,11 +1832,9 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
},
},
},
}}}
}}
tx.Creds = append(tx.Creds, &Credential{
Cred: &testVerifiable{},
})
tx.Creds = append(tx.Creds, &testVerifiable{})
b, err = vm.codec.Marshal(tx)
if err != nil {
@ -1869,11 +1843,11 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {
@ -1920,7 +1894,7 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
pendingTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
pendingTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -1957,7 +1931,7 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&pendingTx.UnsignedTx)
if err != nil {
@ -1972,11 +1946,9 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
pendingTx.Creds = append(pendingTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
pendingTx.Creds = append(pendingTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -1999,7 +1971,7 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
vm.PendingTxs()
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -2021,13 +1993,11 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
},
},
},
}}}
}}
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
[crypto.SECP256K1RSigLen]byte{},
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
[crypto.SECP256K1RSigLen]byte{},
},
})
@ -2038,11 +2008,11 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
tx.Initialize(b)
uTx := &UniqueTx{
TxState: &TxState{
Tx: tx,
},
vm: vm,
txID: tx.ID(),
t: &txState{
tx: tx,
},
}
if err := tx.UnsignedTx.SemanticVerify(vm, uTx, tx.Creds); err == nil {

View File

@ -11,6 +11,7 @@ import (
"github.com/ava-labs/gecko/snow"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
const (
@ -111,7 +112,7 @@ func (t *CreateAssetTx) SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs
}
// SemanticVerify that this transaction is well-formed.
func (t *CreateAssetTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) error {
func (t *CreateAssetTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiable) error {
return t.BaseTx.SemanticVerify(vm, uTx, creds)
}

View File

@ -1,36 +0,0 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package avm
import (
"errors"
"github.com/ava-labs/gecko/vms/components/verify"
)
var (
errNilCredential = errors.New("nil credential is not valid")
errNilFxCredential = errors.New("nil feature extension credential is not valid")
)
// Credential ...
type Credential struct {
Cred verify.Verifiable `serialize:"true"`
}
// Credential returns the feature extension credential that this Credential is
// using.
func (cred *Credential) Credential() verify.Verifiable { return cred.Cred }
// Verify implements the verify.Verifiable interface
func (cred *Credential) Verify() error {
switch {
case cred == nil:
return errNilCredential
case cred.Cred == nil:
return errNilFxCredential
default:
return cred.Cred.Verify()
}
}

View File

@ -1,36 +0,0 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package avm
import (
"testing"
)
func TestCredentialVerifyNil(t *testing.T) {
cred := (*Credential)(nil)
if err := cred.Verify(); err == nil {
t.Fatalf("Should have errored due to nil credential")
}
}
func TestCredentialVerifyNilFx(t *testing.T) {
cred := &Credential{}
if err := cred.Verify(); err == nil {
t.Fatalf("Should have errored due to nil fx credential")
}
}
func TestCredential(t *testing.T) {
cred := &Credential{
Cred: &testVerifiable{},
}
if err := cred.Verify(); err != nil {
t.Fatal(err)
}
if cred.Credential() != cred.Cred {
t.Fatalf("Should have returned the fx credential")
}
}

View File

@ -9,7 +9,6 @@ import (
"sort"
"github.com/ava-labs/gecko/utils"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
@ -21,55 +20,6 @@ var (
errNilOperableFxInput = errors.New("nil operable feature extension input is not valid")
)
// OperableOutput ...
type OperableOutput struct {
Out verify.Verifiable `serialize:"true"`
}
// Output returns the feature extension output that this Output is using.
func (out *OperableOutput) Output() verify.Verifiable { return out.Out }
// Verify implements the verify.Verifiable interface
func (out *OperableOutput) Verify() error {
switch {
case out == nil:
return errNilOperableOutput
case out.Out == nil:
return errNilOperableFxOutput
default:
return out.Out.Verify()
}
}
type innerSortOperableOutputs struct {
outs []*OperableOutput
codec codec.Codec
}
func (outs *innerSortOperableOutputs) Less(i, j int) bool {
iOut := outs.outs[i]
jOut := outs.outs[j]
iBytes, err := outs.codec.Marshal(&iOut.Out)
if err != nil {
return false
}
jBytes, err := outs.codec.Marshal(&jOut.Out)
if err != nil {
return false
}
return bytes.Compare(iBytes, jBytes) == -1
}
func (outs *innerSortOperableOutputs) Len() int { return len(outs.outs) }
func (outs *innerSortOperableOutputs) Swap(i, j int) { o := outs.outs; o[j], o[i] = o[i], o[j] }
func sortOperableOutputs(outs []*OperableOutput, c codec.Codec) {
sort.Sort(&innerSortOperableOutputs{outs: outs, codec: c})
}
func isSortedOperableOutputs(outs []*OperableOutput, c codec.Codec) bool {
return sort.IsSorted(&innerSortOperableOutputs{outs: outs, codec: c})
}
// OperableInput ...
type OperableInput struct {
UTXOID `serialize:"true"`

View File

@ -7,76 +7,8 @@ import (
"testing"
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/vms/components/codec"
)
func TestOperableOutputVerifyNil(t *testing.T) {
oo := (*OperableOutput)(nil)
if err := oo.Verify(); err == nil {
t.Fatalf("Should have errored due to nil operable output")
}
}
func TestOperableOutputVerifyNilFx(t *testing.T) {
oo := &OperableOutput{}
if err := oo.Verify(); err == nil {
t.Fatalf("Should have errored due to nil operable fx output")
}
}
func TestOperableOutputVerify(t *testing.T) {
oo := &OperableOutput{
Out: &testVerifiable{},
}
if err := oo.Verify(); err != nil {
t.Fatal(err)
}
if oo.Output() != oo.Out {
t.Fatalf("Should have returned the fx output")
}
}
func TestOperableOutputSorting(t *testing.T) {
c := codec.NewDefault()
c.RegisterType(&TestTransferable{})
c.RegisterType(&testVerifiable{})
outs := []*OperableOutput{
&OperableOutput{
Out: &TestTransferable{Val: 1},
},
&OperableOutput{
Out: &TestTransferable{Val: 0},
},
&OperableOutput{
Out: &TestTransferable{Val: 0},
},
&OperableOutput{
Out: &testVerifiable{},
},
}
if isSortedOperableOutputs(outs, c) {
t.Fatalf("Shouldn't be sorted")
}
sortOperableOutputs(outs, c)
if !isSortedOperableOutputs(outs, c) {
t.Fatalf("Should be sorted")
}
if result := outs[0].Out.(*TestTransferable).Val; result != 0 {
t.Fatalf("Val expected: %d ; result: %d", 0, result)
}
if result := outs[1].Out.(*TestTransferable).Val; result != 0 {
t.Fatalf("Val expected: %d ; result: %d", 0, result)
}
if result := outs[2].Out.(*TestTransferable).Val; result != 1 {
t.Fatalf("Val expected: %d ; result: %d", 0, result)
}
if _, ok := outs[3].Out.(*testVerifiable); !ok {
t.Fatalf("testVerifiable expected")
}
}
func TestOperableInputVerifyNil(t *testing.T) {
oi := (*OperableInput)(nil)
if err := oi.Verify(); err == nil {

View File

@ -10,6 +10,7 @@ import (
"github.com/ava-labs/gecko/utils"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
var (
@ -21,8 +22,8 @@ var (
type Operation struct {
Asset `serialize:"true"`
Ins []*OperableInput `serialize:"true"`
Outs []*OperableOutput `serialize:"true"`
Ins []*OperableInput `serialize:"true"`
Outs []verify.Verifiable `serialize:"true"`
}
// Verify implements the verify.Verifiable interface
@ -48,7 +49,7 @@ func (op *Operation) Verify(c codec.Codec) error {
return err
}
}
if !isSortedOperableOutputs(op.Outs, c) {
if !isSortedVerifiables(op.Outs, c) {
return errOutputsNotSorted
}

View File

@ -8,6 +8,7 @@ import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
func TestOperationVerifyNil(t *testing.T) {
@ -45,21 +46,6 @@ func TestOperationVerifyInvalidInput(t *testing.T) {
}
}
func TestOperationVerifyInvalidOutput(t *testing.T) {
c := codec.NewDefault()
op := &Operation{
Asset: Asset{
ID: ids.Empty,
},
Outs: []*OperableOutput{
&OperableOutput{},
},
}
if err := op.Verify(c); err == nil {
t.Fatalf("Should have errored due to an invalid output")
}
}
func TestOperationVerifyInputsNotSorted(t *testing.T) {
c := codec.NewDefault()
op := &Operation{
@ -96,13 +82,9 @@ func TestOperationVerifyOutputsNotSorted(t *testing.T) {
Asset: Asset{
ID: ids.Empty,
},
Outs: []*OperableOutput{
&OperableOutput{
Out: &TestTransferable{Val: 1},
},
&OperableOutput{
Out: &TestTransferable{Val: 0},
},
Outs: []verify.Verifiable{
&TestTransferable{Val: 1},
&TestTransferable{Val: 0},
},
}
if err := op.Verify(c); err == nil {
@ -116,10 +98,8 @@ func TestOperationVerify(t *testing.T) {
Asset: Asset{
ID: ids.Empty,
},
Outs: []*OperableOutput{
&OperableOutput{
Out: &testVerifiable{},
},
Outs: []verify.Verifiable{
&testVerifiable{},
},
}
if err := op.Verify(c); err != nil {

View File

@ -9,6 +9,7 @@ import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/snow"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
var (
@ -63,7 +64,7 @@ func (t *OperationTx) UTXOs() []*UTXO {
Asset: Asset{
ID: asset,
},
Out: out.Out,
Out: out,
})
}
}
@ -106,7 +107,7 @@ func (t *OperationTx) SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs i
}
// SemanticVerify that this transaction is well-formed.
func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) error {
func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiable) error {
if err := t.BaseTx.SemanticVerify(vm, uTx, creds); err != nil {
return err
}
@ -123,7 +124,7 @@ func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential)
ins = append(ins, in.In)
cred := creds[i+offset]
credIntfs = append(credIntfs, cred.Cred)
credIntfs = append(credIntfs, cred)
utxoID := in.InputID()
utxo, err := vm.state.UTXO(utxoID)
@ -165,7 +166,7 @@ func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential)
}
offset += len(op.Ins)
for _, out := range op.Outs {
outs = append(outs, out.Out)
outs = append(outs, out)
}
var fxObj interface{}

View File

@ -29,7 +29,7 @@ func TestPrefixedSetsAndGets(t *testing.T) {
Out: &testVerifiable{},
}
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -51,7 +51,7 @@ func TestPrefixedSetsAndGets(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(tx.UnsignedTx)
if err != nil {
@ -66,11 +66,9 @@ func TestPrefixedSetsAndGets(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})

View File

@ -163,7 +163,7 @@ func (service *Service) GetAssetDescription(_ *http.Request, args *GetAssetDescr
if status := tx.Status(); !status.Fetched() {
return errUnknownAssetID
}
createAssetTx, ok := tx.t.tx.UnsignedTx.(*CreateAssetTx)
createAssetTx, ok := tx.UnsignedTx.(*CreateAssetTx)
if !ok {
return errTxNotCreateAsset
}
@ -700,7 +700,7 @@ func (service *Service) Send(r *http.Request, args *SendArgs, reply *SendReply)
cred.Sigs = append(cred.Sigs, fixedSig)
}
tx.Creds = append(tx.Creds, &Credential{Cred: cred})
tx.Creds = append(tx.Creds, cred)
}
b, err := service.vm.codec.Marshal(tx)
@ -849,19 +849,15 @@ func (service *Service) CreateMintTx(r *http.Request, args *CreateMintTxArgs, re
},
},
},
Outs: []*OperableOutput{
&OperableOutput{
&secp256k1fx.MintOutput{
OutputOwners: out.OutputOwners,
},
Outs: []verify.Verifiable{
&secp256k1fx.MintOutput{
OutputOwners: out.OutputOwners,
},
&OperableOutput{
&secp256k1fx.TransferOutput{
Amt: uint64(args.Amount),
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{to},
},
&secp256k1fx.TransferOutput{
Amt: uint64(args.Amount),
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{to},
},
},
},
@ -963,11 +959,11 @@ func (service *Service) SignMintTx(r *http.Request, args *SignMintTxArgs, reply
}
if len(tx.Creds) == 0 {
tx.Creds = append(tx.Creds, &Credential{Cred: &secp256k1fx.Credential{}})
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{})
}
cred := tx.Creds[0]
switch cred := cred.Cred.(type) {
switch cred := cred.(type) {
case *secp256k1fx.Credential:
if len(cred.Sigs) != size {
cred.Sigs = make([][crypto.SECP256K1RSigLen]byte, size)

View File

@ -250,7 +250,7 @@ func TestStateTXs(t *testing.T) {
t.Fatalf("Should have errored when reading tx")
}
tx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
tx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -272,7 +272,7 @@ func TestStateTXs(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(tx.UnsignedTx)
if err != nil {
@ -287,11 +287,9 @@ func TestStateTXs(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
tx.Creds = append(tx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})

View File

@ -10,6 +10,7 @@ import (
"github.com/ava-labs/gecko/snow"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
)
var (
@ -31,7 +32,7 @@ type UnsignedTx interface {
InputUTXOs() []*UTXOID
UTXOs() []*UTXO
SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs int) error
SemanticVerify(vm *VM, uTx *UniqueTx, creds []*Credential) error
SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiable) error
}
// Tx is the core operation that can be performed. The tx uses the UTXO model.
@ -42,12 +43,12 @@ type UnsignedTx interface {
type Tx struct {
UnsignedTx `serialize:"true"`
Creds []*Credential `serialize:"true"` // The credentials of this transaction
Creds []verify.Verifiable `serialize:"true"` // The credentials of this transaction
}
// Credentials describes the authorization that allows the Inputs to consume the
// specified UTXOs. The returned array should not be modified.
func (t *Tx) Credentials() []*Credential { return t.Creds }
func (t *Tx) Credentials() []verify.Verifiable { return t.Creds }
// SyntacticVerify verifies that this transaction is well-formed.
func (t *Tx) SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs int) error {

View File

@ -9,6 +9,7 @@ import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/utils/units"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
"github.com/ava-labs/gecko/vms/secp256k1fx"
)
@ -45,7 +46,7 @@ func TestTxInvalidCredential(t *testing.T) {
c.RegisterType(&testVerifiable{})
tx := &Tx{
UnsignedTx: &OperationTx{BaseTx: BaseTx{
UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -67,11 +68,9 @@ func TestTxInvalidCredential(t *testing.T) {
},
},
},
}},
Creds: []*Credential{
&Credential{
Cred: &testVerifiable{err: errUnneededAddress},
},
},
Creds: []verify.Verifiable{
&testVerifiable{err: errUnneededAddress},
},
}
@ -99,7 +98,7 @@ func TestTxInvalidUnsignedTx(t *testing.T) {
c.RegisterType(&testVerifiable{})
tx := &Tx{
UnsignedTx: &OperationTx{BaseTx: BaseTx{
UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -138,14 +137,10 @@ func TestTxInvalidUnsignedTx(t *testing.T) {
},
},
},
}},
Creds: []*Credential{
&Credential{
Cred: &testVerifiable{},
},
&Credential{
Cred: &testVerifiable{},
},
},
Creds: []verify.Verifiable{
&testVerifiable{},
&testVerifiable{},
},
}
@ -214,10 +209,8 @@ func TestTxInvalidNumberOfCredentials(t *testing.T) {
},
},
},
Creds: []*Credential{
&Credential{
Cred: &testVerifiable{},
},
Creds: []verify.Verifiable{
&testVerifiable{},
},
}

View File

@ -21,16 +21,19 @@ var (
// UniqueTx provides a de-duplication service for txs. This only provides a
// performance boost
type UniqueTx struct {
*TxState
vm *VM
txID ids.ID
t *txState
}
type txState struct {
// TxState ...
type TxState struct {
*Tx
unique, verifiedTx, verifiedState bool
validity error
tx *Tx
inputs ids.Set
inputUTXOs []*UTXOID
utxos []*UTXO
@ -42,51 +45,51 @@ type txState struct {
}
func (tx *UniqueTx) refresh() {
if tx.t == nil {
tx.t = &txState{}
if tx.TxState == nil {
tx.TxState = &TxState{}
}
if tx.t.unique {
if tx.unique {
return
}
unique := tx.vm.state.UniqueTx(tx)
prevTx := tx.t.tx
prevTx := tx.Tx
if unique == tx {
// If no one was in the cache, make sure that there wasn't an
// intermediate object whose state I must reflect
if status, err := tx.vm.state.Status(tx.ID()); err == nil {
tx.t.status = status
tx.t.unique = true
tx.status = status
tx.unique = true
}
} else {
// If someone is in the cache, they must be up to date
// This ensures that every unique tx object points to the same tx state
tx.t = unique.t
tx.TxState = unique.TxState
}
if tx.t.tx != nil {
if tx.Tx != nil {
return
}
if prevTx == nil {
if innerTx, err := tx.vm.state.Tx(tx.ID()); err == nil {
tx.t.tx = innerTx
tx.Tx = innerTx
}
} else {
tx.t.tx = prevTx
tx.Tx = prevTx
}
}
// Evict is called when this UniqueTx will no longer be returned from a cache
// lookup
func (tx *UniqueTx) Evict() { tx.t.unique = false } // Lock is already held here
func (tx *UniqueTx) Evict() { tx.unique = false } // Lock is already held here
func (tx *UniqueTx) setStatus(status choices.Status) error {
tx.refresh()
if tx.t.status == status {
if tx.status == status {
return nil
}
tx.t.status = status
tx.status = status
return tx.vm.state.SetStatus(tx.ID(), status)
}
@ -125,10 +128,10 @@ func (tx *UniqueTx) Accept() {
tx.vm.pubsub.Publish("accepted", txID)
tx.t.deps = nil // Needed to prevent a memory leak
tx.deps = nil // Needed to prevent a memory leak
if tx.t.onDecide != nil {
tx.t.onDecide(choices.Accepted)
if tx.onDecide != nil {
tx.onDecide(choices.Accepted)
}
}
@ -148,24 +151,24 @@ func (tx *UniqueTx) Reject() {
tx.vm.pubsub.Publish("rejected", txID)
tx.t.deps = nil // Needed to prevent a memory leak
tx.deps = nil // Needed to prevent a memory leak
if tx.t.onDecide != nil {
tx.t.onDecide(choices.Rejected)
if tx.onDecide != nil {
tx.onDecide(choices.Rejected)
}
}
// Status returns the current status of this transaction
func (tx *UniqueTx) Status() choices.Status {
tx.refresh()
return tx.t.status
return tx.status
}
// Dependencies returns the set of transactions this transaction builds on
func (tx *UniqueTx) Dependencies() []snowstorm.Tx {
tx.refresh()
if tx.t.tx == nil || len(tx.t.deps) != 0 {
return tx.t.deps
if tx.Tx == nil || len(tx.deps) != 0 {
return tx.deps
}
txIDs := ids.Set{}
@ -173,61 +176,61 @@ func (tx *UniqueTx) Dependencies() []snowstorm.Tx {
txID, _ := in.InputSource()
if !txIDs.Contains(txID) {
txIDs.Add(txID)
tx.t.deps = append(tx.t.deps, &UniqueTx{
tx.deps = append(tx.deps, &UniqueTx{
vm: tx.vm,
txID: txID,
})
}
}
for _, assetID := range tx.t.tx.AssetIDs().List() {
for _, assetID := range tx.Tx.AssetIDs().List() {
if !txIDs.Contains(assetID) {
txIDs.Add(assetID)
tx.t.deps = append(tx.t.deps, &UniqueTx{
tx.deps = append(tx.deps, &UniqueTx{
vm: tx.vm,
txID: assetID,
})
}
}
return tx.t.deps
return tx.deps
}
// InputIDs returns the set of utxoIDs this transaction consumes
func (tx *UniqueTx) InputIDs() ids.Set {
tx.refresh()
if tx.t.tx == nil || tx.t.inputs.Len() != 0 {
return tx.t.inputs
if tx.Tx == nil || tx.inputs.Len() != 0 {
return tx.inputs
}
for _, utxo := range tx.InputUTXOs() {
tx.t.inputs.Add(utxo.InputID())
tx.inputs.Add(utxo.InputID())
}
return tx.t.inputs
return tx.inputs
}
// InputUTXOs returns the utxos that will be consumed on tx acceptance
func (tx *UniqueTx) InputUTXOs() []*UTXOID {
tx.refresh()
if tx.t.tx == nil || len(tx.t.inputUTXOs) != 0 {
return tx.t.inputUTXOs
if tx.Tx == nil || len(tx.inputUTXOs) != 0 {
return tx.inputUTXOs
}
tx.t.inputUTXOs = tx.t.tx.InputUTXOs()
return tx.t.inputUTXOs
tx.inputUTXOs = tx.Tx.InputUTXOs()
return tx.inputUTXOs
}
// UTXOs returns the utxos that will be added to the UTXO set on tx acceptance
func (tx *UniqueTx) UTXOs() []*UTXO {
tx.refresh()
if tx.t.tx == nil || len(tx.t.utxos) != 0 {
return tx.t.utxos
if tx.Tx == nil || len(tx.utxos) != 0 {
return tx.utxos
}
tx.t.utxos = tx.t.tx.UTXOs()
return tx.t.utxos
tx.utxos = tx.Tx.UTXOs()
return tx.utxos
}
// Bytes returns the binary representation of this transaction
func (tx *UniqueTx) Bytes() []byte {
tx.refresh()
return tx.t.tx.Bytes()
return tx.Tx.Bytes()
}
// Verify the validity of this transaction
@ -248,39 +251,39 @@ func (tx *UniqueTx) Verify() error {
func (tx *UniqueTx) SyntacticVerify() error {
tx.refresh()
if tx.t.tx == nil {
if tx.Tx == nil {
return errUnknownTx
}
if tx.t.verifiedTx {
return tx.t.validity
if tx.verifiedTx {
return tx.validity
}
tx.t.verifiedTx = true
tx.t.validity = tx.t.tx.SyntacticVerify(tx.vm.ctx, tx.vm.codec, len(tx.vm.fxs))
return tx.t.validity
tx.verifiedTx = true
tx.validity = tx.Tx.SyntacticVerify(tx.vm.ctx, tx.vm.codec, len(tx.vm.fxs))
return tx.validity
}
// SemanticVerify the validity of this transaction
func (tx *UniqueTx) SemanticVerify() error {
tx.SyntacticVerify()
if tx.t.validity != nil || tx.t.verifiedState {
return tx.t.validity
if tx.validity != nil || tx.verifiedState {
return tx.validity
}
tx.t.verifiedState = true
tx.t.validity = tx.t.tx.SemanticVerify(tx.vm, tx)
tx.verifiedState = true
tx.validity = tx.Tx.SemanticVerify(tx.vm, tx)
if tx.t.validity == nil {
if tx.validity == nil {
tx.vm.pubsub.Publish("verified", tx.ID())
}
return tx.t.validity
return tx.validity
}
// UnsignedBytes returns the unsigned bytes of the transaction
func (tx *UniqueTx) UnsignedBytes() []byte {
b, err := tx.vm.codec.Marshal(&tx.t.tx.UnsignedTx)
b, err := tx.vm.codec.Marshal(&tx.UnsignedTx)
tx.vm.ctx.Log.AssertNoError(err)
return b
}

View File

@ -264,7 +264,7 @@ func (vm *VM) IssueTx(b []byte, onDecide func(choices.Status)) (ids.ID, error) {
return ids.ID{}, err
}
vm.issueTx(tx)
tx.t.onDecide = onDecide
tx.onDecide = onDecide
return tx.ID(), nil
}
@ -402,18 +402,18 @@ func (vm *VM) parseTx(b []byte) (*UniqueTx, error) {
rawTx.Initialize(b)
tx := &UniqueTx{
TxState: &TxState{
Tx: rawTx,
},
vm: vm,
txID: rawTx.ID(),
t: &txState{
tx: rawTx,
},
}
if err := tx.SyntacticVerify(); err != nil {
return nil, err
}
if tx.Status() == choices.Unknown {
if err := vm.state.SetTx(tx.ID(), tx.t.tx); err != nil {
if err := vm.state.SetTx(tx.ID(), tx.Tx); err != nil {
return nil, err
}
tx.setStatus(choices.Processing)
@ -449,7 +449,7 @@ func (vm *VM) verifyFxUsage(fxID int, assetID ids.ID) bool {
if status := tx.Status(); !status.Fetched() {
return false
}
createAssetTx, ok := tx.t.tx.UnsignedTx.(*CreateAssetTx)
createAssetTx, ok := tx.UnsignedTx.(*CreateAssetTx)
if !ok {
return false
}

View File

@ -16,6 +16,7 @@ import (
"github.com/ava-labs/gecko/utils/hashing"
"github.com/ava-labs/gecko/utils/units"
"github.com/ava-labs/gecko/vms/components/codec"
"github.com/ava-labs/gecko/vms/components/verify"
"github.com/ava-labs/gecko/vms/secp256k1fx"
)
@ -300,13 +301,11 @@ func TestTxSerialization(t *testing.T) {
Asset: Asset{
ID: asset,
},
Outs: []*OperableOutput{
&OperableOutput{
Out: &secp256k1fx.MintOutput{
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{keys[0].PublicKey().Address()},
},
Outs: []verify.Verifiable{
&secp256k1fx.MintOutput{
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{keys[0].PublicKey().Address()},
},
},
},
@ -441,7 +440,7 @@ func TestIssueTx(t *testing.T) {
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
newTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
newTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -463,7 +462,7 @@ func TestIssueTx(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&newTx.UnsignedTx)
if err != nil {
@ -478,11 +477,9 @@ func TestIssueTx(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
newTx.Creds = append(newTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
newTx.Creds = append(newTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -576,7 +573,7 @@ func TestIssueDependentTx(t *testing.T) {
key := keys[0]
firstTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
firstTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -608,7 +605,7 @@ func TestIssueDependentTx(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err := vm.codec.Marshal(&firstTx.UnsignedTx)
if err != nil {
@ -622,11 +619,9 @@ func TestIssueDependentTx(t *testing.T) {
fixedSig := [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
firstTx.Creds = append(firstTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
firstTx.Creds = append(firstTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})
@ -641,7 +636,7 @@ func TestIssueDependentTx(t *testing.T) {
t.Fatal(err)
}
secondTx := &Tx{UnsignedTx: &OperationTx{BaseTx: BaseTx{
secondTx := &Tx{UnsignedTx: &BaseTx{
NetID: networkID,
BCID: chainID,
Ins: []*TransferableInput{
@ -661,7 +656,7 @@ func TestIssueDependentTx(t *testing.T) {
},
},
},
}}}
}}
unsignedBytes, err = vm.codec.Marshal(&secondTx.UnsignedTx)
if err != nil {
@ -675,11 +670,9 @@ func TestIssueDependentTx(t *testing.T) {
fixedSig = [crypto.SECP256K1RSigLen]byte{}
copy(fixedSig[:], sig)
secondTx.Creds = append(secondTx.Creds, &Credential{
Cred: &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
secondTx.Creds = append(secondTx.Creds, &secp256k1fx.Credential{
Sigs: [][crypto.SECP256K1RSigLen]byte{
fixedSig,
},
})

View File

@ -238,7 +238,7 @@ func (w *Wallet) CreateTx(assetID ids.ID, amount uint64, destAddr ids.ShortID) (
cred.Sigs = append(cred.Sigs, fixedSig)
}
tx.Creds = append(tx.Creds, &avm.Credential{Cred: cred})
tx.Creds = append(tx.Creds, cred)
}
b, err := w.codec.Marshal(tx)