Example #1
0
bool script::run_operation(operation op, 
        const message::transaction& parent_tx, uint32_t input_index)
{
    switch (op.code)
    {
        case opcode::special:
            return true;

        case opcode::pushdata1:
            BITCOIN_ASSERT(op.data.size() == static_cast<size_t>(op.code));
            return true;

        case opcode::pushdata2:
            BITCOIN_ASSERT(op.data.size() == static_cast<size_t>(op.code));
            return true;

        case opcode::pushdata4:
            BITCOIN_ASSERT(op.data.size() == static_cast<size_t>(op.code));
            return true;

        case opcode::dup:
            return op_dup();

        case opcode::hash160:
            return op_hash160();

        case opcode::equalverify:
            return op_equalverify();

        case opcode::checksig:
            return op_checksig(parent_tx, input_index);

        default:
            break;
    }
    return false;
}
// duplicate the frame and queue it
int overlay_forward_payload(struct overlay_frame *f){
  f->ttl--;
  if (f->ttl<=0)
    return 0;
  
  if (debug&DEBUG_OVERLAYFRAMES)
    DEBUGF("Forwarding payload for %s, ttl=%d",
	  (f->destination?alloca_tohex_sid(f->destination->sid):"broadcast"),
	  f->ttl);

  /* Queue frame for dispatch.
   Don't forget to put packet in the correct queue based on type.
   (e.g., mesh management, voice, video, ordinary or opportunistic).
   
   But the really important bit is to clone the frame, since the
   structure we are looking at here must be left as is and returned
   to the caller to do as they please */	  
  struct overlay_frame *qf=op_dup(f);
  if (!qf) 
    return WHY("Could not clone frame for queuing");
  
  // TODO include priority in packet header
  int qn=OQ_ORDINARY;
  /* Make sure voice traffic gets priority */
  if ((qf->type&OF_TYPE_BITS)==OF_TYPE_DATA_VOICE) {
    qn=OQ_ISOCHRONOUS_VOICE;
    rhizome_saw_voice_traffic();
  }
  
  if (overlay_payload_enqueue(qn,qf)) {
    op_free(qf);
    return WHY("failed to enqueue forwarded payload");
  }
  
  return 0;
}
Example #3
0
void StackInterpreter::processOpCode(const OpCode& oc)
{
   ++opcount_;

   //handle push data by itself, doesn't play well with switch
   if (oc.opcode_ == 0)
   {
      op_0();
      return;
   }

   if (oc.opcode_ <= 75)
   {
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ < 79)
   {
      //op push data
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ == OP_1NEGATE)
   {
      op_1negate();
      return;
   }

   if (oc.opcode_ <= 96 && oc.opcode_ >= 81)
   {
      //op_1 - op_16
      uint8_t val = oc.opcode_ - 80;
      stack_.push_back(move(intToRawBinary(val)));
      return;
   }

   //If we got this far this op code is not push data. If this is the input
   //script, set the flag as per P2SH parsing rules (only push data in inputs)
   if (outputScriptRef_.getSize() == 0)
      onlyPushDataInInput_ = false;

   switch (oc.opcode_)
   {
   case OP_NOP:
      break;

   case OP_IF:
   {
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_NOTIF:
   {
      op_not();
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_ELSE:
      //processed by opening if statement
      throw ScriptException("a wild else appears");

   case OP_ENDIF:
      //processed by opening if statement
      throw ScriptException("a wild endif appears");

   case OP_VERIFY:
      op_verify();
      break;

   case OP_TOALTSTACK:
      op_toaltstack();
      break;

   case OP_FROMALTSTACK:
      op_fromaltstack();
      break;

   case OP_IFDUP:
      op_ifdup();
      break;

   case OP_2DROP:
   {
      stack_.pop_back();
      stack_.pop_back();
      break;
   }

   case OP_2DUP:
      op_2dup();
      break;

   case OP_3DUP:
      op_3dup();
      break;

   case OP_2OVER:
      op_2over();
      break;

   case OP_DEPTH:
      op_depth();
      break;

   case OP_DROP:
      stack_.pop_back();
      break;

   case OP_DUP:
      op_dup();
      break;

   case OP_NIP:
      op_nip();
      break;

   case OP_OVER:
      op_over();
      break;

   case OP_PICK:
      op_pick();
      break;

   case OP_ROLL:
      op_roll();
      break;

   case OP_ROT:
      op_rot();
      break;

   case OP_SWAP:
      op_swap();
      break;

   case OP_TUCK:
      op_tuck();
      break;

   case OP_SIZE:
      op_size();
      break;

   case OP_EQUAL:
   {
      op_equal();
      if (onlyPushDataInInput_ && p2shScript_.getSize() != 0)
      {
         //check the op_equal result
         op_verify();
         if (!isValid_)
            break;

         if (flags_ & SCRIPT_VERIFY_SEGWIT)
            if (p2shScript_.getSize() == 22 ||
               p2shScript_.getSize() == 34)
            {
               auto versionByte = p2shScript_.getPtr();
               if (*versionByte <= 16)
               {
                  processSW(p2shScript_);
                  return;
               }
            }

         processScript(p2shScript_, true);
      }
      break;
   }

   case OP_EQUALVERIFY:
   {
      op_equal();
      op_verify();
      break;
   }

   case OP_1ADD:
      op_1add();
      break;

   case OP_1SUB:
      op_1sub();
      break;

   case OP_NEGATE:
      op_negate();
      break;

   case OP_ABS:
      op_abs();
      break;

   case OP_NOT:
      op_not();
      break;

   case OP_0NOTEQUAL:
      op_0notequal();
      break;

   case OP_ADD:
      op_add();
      break;

   case OP_SUB:
      op_sub();
      break;

   case OP_BOOLAND:
      op_booland();
      break;

   case OP_BOOLOR:
      op_boolor();
      break;

   case OP_NUMEQUAL:
      op_numequal();
      break;

   case OP_NUMEQUALVERIFY:
   {
      op_numequal();
      op_verify();
      break;
   }

   case OP_NUMNOTEQUAL:
      op_numnotequal();
      break;

   case OP_LESSTHAN:
      op_lessthan();
      break;

   case OP_GREATERTHAN:
      op_greaterthan();
      break;

   case OP_LESSTHANOREQUAL:
      op_lessthanorequal();
      break;

   case OP_GREATERTHANOREQUAL:
      op_greaterthanorequal();
      break;

   case OP_MIN:
      op_min();
      break;

   case OP_MAX:
      op_max();
      break;

   case OP_WITHIN:
      op_within();
      break;

   case OP_RIPEMD160:
      op_ripemd160();
      break;

   case OP_SHA256:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH_SHA256)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_sha256();
      break;
   }

   case OP_HASH160:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_hash160();
      break;
   }

   case OP_HASH256:
      op_hash256();
      break;

   case OP_CODESEPARATOR:
   {
      opcount_ = 0;
      if (outputScriptRef_.getSize() != 0)
         txStubPtr_->setLastOpCodeSeparator(inputIndex_, oc.offset_);
      break;
   }

   case OP_CHECKSIG:
      op_checksig();
      break;

   case OP_CHECKSIGVERIFY:
   {
      op_checksig();
      op_verify();
      break;
   }

   case OP_CHECKMULTISIG:
      op_checkmultisig();
      break;

   case OP_CHECKMULTISIGVERIFY:
   {
      op_checkmultisig();
      op_verify();
   }

   case OP_NOP1:
      break;

   case OP_NOP2:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
         break; // not enabled; treat as a NOP

      //CLTV mechanics
      throw ScriptException("OP_CLTV not supported");
   }

   case OP_NOP3:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY))
         break; // not enabled; treat as a NOP

      //CSV mechanics
      throw ScriptException("OP_CSV not supported");
   }

   case OP_NOP4:
      break;

   case OP_NOP5:
      break;

   case OP_NOP6:
      break;

   case OP_NOP7:
      break;

   case OP_NOP8:
      break;

   case OP_NOP9:
      break;

   case OP_NOP10:
      break;

   default:
   {
      stringstream ss;
      ss << "unknown opcode: " << (unsigned)oc.opcode_;
      throw runtime_error(ss.str());
   }
   }
}
Example #4
0
void StackResolver::processOpCode(const OpCode& oc)
{
   if (oc.opcode_ >= 1 && oc.opcode_ <= 75)
   {
      pushdata(oc.dataRef_);
      return;
   }

   if (oc.opcode_ >= 81 && oc.opcode_ <= 96)
   {
      unsigned val = oc.opcode_ - 80;
      push_int(val);
      return;
   }

   opCodeCount_++;
   switch (oc.opcode_)
   {
   case OP_0:
      pushdata(BinaryData());
      break;

   case OP_PUSHDATA1:
   case OP_PUSHDATA2:
   case OP_PUSHDATA4:
      pushdata(oc.dataRef_);
      break;

   case OP_DUP:
      op_dup();
      break;

   case OP_HASH160:
   case OP_SHA256:
   {
      opHash_ = true;
      op_1item_verify(oc);
      break;
   }

   case OP_RIPEMD160:
   case OP_HASH256:
      op_1item_verify(oc);
      break;

   case OP_EQUAL:
   {
      if (opCodeCount_ == 2 && opHash_)
         isP2SH_ = true;
      op_2items(oc);
      break;
   }

   case OP_CHECKSIG:
      op_2items(oc);
      break;

   case OP_EQUALVERIFY:
   case OP_CHECKSIGVERIFY:
      op_2items_verify(oc);
      break;

   case OP_CHECKMULTISIG:
   case OP_CHECKMULTISIGVERIFY:
      push_op_code(oc);
      break;

   default:
      throw ScriptException("opcode not implemented with reverse stack");
   }
}