Merge pull request #22 from ava-labs/x-mint

Fixed mint signing
This commit is contained in:
Stephen Buttolph 2020-03-31 15:34:23 -04:00 committed by GitHub
commit c43d77da30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 53 additions and 47 deletions

View File

@ -869,71 +869,77 @@ func (service *Service) SignMintTx(r *http.Request, args *SignMintTxArgs, reply
return fmt.Errorf("problem creating transaction: %w", err)
}
inputUTXOs := tx.InputUTXOs()
if len(inputUTXOs) != 1 {
opTx, ok := tx.UnsignedTx.(*OperationTx)
if !ok {
return errors.New("transaction must be a mint transaction")
}
if len(opTx.Ins) != 0 {
return errCanOnlySignSingleInputTxs
}
inputUTXO := inputUTXOs[0]
if len(opTx.Ops) != 1 {
return errCanOnlySignSingleInputTxs
}
op := opTx.Ops[0]
inputTxID, utxoIndex := inputUTXO.InputSource()
utx := UniqueTx{
vm: service.vm,
txID: inputTxID,
if len(op.UTXOIDs) != 1 {
return errCanOnlySignSingleInputTxs
}
if !utx.Status().Fetched() {
return errUnknownUTXO
}
utxos := utx.UTXOs()
if uint32(len(utxos)) <= utxoIndex {
return errInvalidUTXO
inputUTXO := op.UTXOIDs[0]
utxo, err := service.vm.getUTXO(inputUTXO)
if err != nil {
return err
}
utxo := utxos[int(utxoIndex)]
i := -1
size := 0
switch out := utxo.Out.(type) {
case *secp256k1fx.MintOutput:
size = int(out.Threshold)
for j, addr := range out.Addrs {
if bytes.Equal(addr.Bytes(), minter) {
i = j
break
}
}
default:
out, ok := utxo.Out.(*secp256k1fx.MintOutput)
if !ok {
return errUnknownOutputType
}
if i == -1 {
return errUnneededAddress
secpOp, ok := op.Op.(*secp256k1fx.MintOperation)
if !ok {
return errors.New("unknown mint operation")
}
sigIndex := -1
size := int(out.Threshold)
for i, addrIndex := range secpOp.MintInput.SigIndices {
if addrIndex >= uint32(len(out.Addrs)) {
return errors.New("input output mismatch")
}
if bytes.Equal(out.Addrs[int(addrIndex)].Bytes(), minter) {
sigIndex = i
break
}
}
if sigIndex == -1 {
return errUnneededAddress
}
if len(tx.Creds) == 0 {
tx.Creds = append(tx.Creds, &secp256k1fx.Credential{})
}
cred := tx.Creds[0]
switch cred := cred.(type) {
case *secp256k1fx.Credential:
if len(cred.Sigs) != size {
cred.Sigs = make([][crypto.SECP256K1RSigLen]byte, size)
}
unsignedBytes, err := service.vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
return fmt.Errorf("problem creating transaction: %w", err)
}
sig, err := sk.Sign(unsignedBytes)
if err != nil {
return fmt.Errorf("problem signing transaction: %w", err)
}
copy(cred.Sigs[i][:], sig)
default:
cred, ok := tx.Creds[0].(*secp256k1fx.Credential)
if !ok {
return errUnknownCredentialType
}
if len(cred.Sigs) != size {
cred.Sigs = make([][crypto.SECP256K1RSigLen]byte, size)
}
unsignedBytes, err := service.vm.codec.Marshal(&tx.UnsignedTx)
if err != nil {
return fmt.Errorf("problem creating transaction: %w", err)
}
sig, err := sk.Sign(unsignedBytes)
if err != nil {
return fmt.Errorf("problem signing transaction: %w", err)
}
copy(cred.Sigs[sigIndex][:], sig)
txBytes, err := service.vm.codec.Marshal(&tx)
if err != nil {
return fmt.Errorf("problem creating transaction: %w", err)